package net.tycmc.cty.ctyms.timejob.iems.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.configuration.ConfigurationException;

import net.tycmc.bulb.common.dao.IBaseDAO;
import net.tycmc.bulb.common.dao.ITransactionDAO;
import net.tycmc.bulb.common.util.MapGetter;
import net.tycmc.bulb.common.util.StringUtil;
import net.tycmc.bulb.dbutil.global.GlobalDBVar;
import net.tycmc.cty.ctyms.timejob.common.DateControl;
import net.tycmc.cty.ctyms.timejob.common.DynamicReadConfig;
import net.tycmc.cty.ctyms.timejob.common.MyConnectDSTransDAO;

/**
 * 统计设备健康状态处理类
 * @author jiyongtian
 *
 */
public class VclHealthStateService {
	private IBaseDAO baseDAO;
	private ITransactionDAO tranDAO;
	public VclHealthStateService(){
		   
	}
    public IBaseDAO getBaseDAO() {
		return baseDAO;
	}
	public void setBaseDAO(IBaseDAO baseDAO) {
		this.baseDAO = baseDAO;
	}
	public ITransactionDAO getTranDAO() {
		return tranDAO;
	}
	public void setTranDAO(ITransactionDAO tranDAO) {
		this.tranDAO = tranDAO;
	}
	public void healthStateStart(){
		//获取设备当前时间的开关机状态
		List<Map<String,Object>> openState = this.getVclOpenState();
		//获取预计完成时间大于当前时间的维修保养停机记录
		List<Map<String,Object>>[] stopRecord = this.getUndoneStopRecord();
		//获取当前时间有未解除故障的设备（,设备id1,设备id2,设备id3,）
		String fltVcl = this.getActiveFltVcl();
		
		//二期优化：是否需要备份数据
		String isbakTable="";
		try {
			isbakTable = DynamicReadConfig.getConfigProperty("config.properties", "HealthStat");
		} catch (ConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(!StringUtil.isValid(isbakTable)){
			isbakTable = "0";
		}
				
		
		List<Map<String,String>> healthList = new ArrayList<Map<String,String>>();
		
		for(Map<String,Object> map:openState){
			Map<String,String> healthMap = new HashMap<String,String>();
			String vclid = MapGetter.getString(map, "vclid");
			//设备ID为null
			if(!StringUtil.isValid(vclid)){
				continue;
			};
			healthMap.put("vclid", vclid);
			String ivclHealth = "";
			String keyState = MapGetter.getString(map, "keystate");
			String engineState = MapGetter.getString(map, "enginestate");
			//开机状态keystate=1, enginestate = 1：先校验是否有未解除故障，再校验是否有完成日期大于当前时间停机记录
			if(StringUtil.isValid(keyState)&&keyState.equals("1")
					&&StringUtil.isValid(engineState)&&engineState.equals("1")){
				String onVclid = ","+vclid+",";
				//有未解除故障
				if(fltVcl.indexOf(onVclid) >=0 ){
					ivclHealth="4";//健康状态为故障报警
				}
				//无未解除故障，校验是否有完成日期大于当前时间的停机记录
				else{
					String onHealth = this.haveMtnRStopRecord(map, stopRecord, "vclid");
					//有完成日期大于当前时间停机记录
					if(StringUtil.isValid(onHealth)){
						ivclHealth = onHealth;
					}
					//无完成日期大于当前时间停机记录
					else{
						ivclHealth="1";//健康状态为正常
					}
				}			
			}
			//关机：先校验是否有完成日期大于当前时间停机记录，再校验是否有现行故障，
			else{
				String offHealth = this.haveMtnRStopRecord(map,stopRecord,"vclid");
				//有完成日期大于当前时间停机记录
				if(StringUtil.isValid(offHealth)){
					ivclHealth = offHealth;
				}
				//该设备不存在完成时间大于当前时间的维修保养停机记录,校验是否有故障
				else{
				   	String offVclid=","+vclid+",";
				   	//有未解除故障
				   	if(fltVcl.indexOf(offVclid)>=0){
				   		ivclHealth="4";//健康状态为故障报警
				   	}
				   	//无未解除故障
				   	else{
				   		ivclHealth="1";//健康状态为正常
				   	}					
				}
			}
			healthMap.put("healthstate", ivclHealth);
			healthList.add(healthMap);			
		}
		this.insertMegVclHealthState(healthList,isbakTable);
	}
	/**
	 * 保存设备健康率
	 * @param List<Map<String, String>> healthList 
	 **/
	private void insertMegVclHealthState(List<Map<String, String>> healthList,String isbakTable) {
		MyConnectDSTransDAO myConnectDSTransDAO=new MyConnectDSTransDAO();
		String now = DateControl.getDateTime(0);
		List<String> inList = new ArrayList<String>();
			String sql=" delete from Message_VclState_Health";
			inList.add(sql);
		for(Map<String,String> oneMap:healthList){
			StringBuffer inStrBuf = new StringBuffer();
			inStrBuf.append("insert into Message_VclState_Health(MsgVH_VclID,MsgVH_State,MsgVH_UntilTime)");
			inStrBuf.append("values("+MapGetter.getString(oneMap, "vclid")+","+MapGetter.getString(oneMap, "healthstate")+",'"+now+"')");
			inList.add(inStrBuf.toString());
		}
		myConnectDSTransDAO.batch(inList);
		if(isbakTable.equals("1")){
			MyConnectDSTransDAO conn=new MyConnectDSTransDAO(true);
			boolean flager = conn.batch(inList);
			if(!flager){
				System.out.println("保存设备健康率备份！！");
			}
		}
	}
	/**
	 * 根据设备是否有完成时间大于当前时间的维修停机记录
	 * 返回设备健康状态
	 * @param Map<String, Object> map 一台设备：设备ID、key状态、engine状体
	 * @param List<Map<String, Object>>[] stopRecord 完成时间大于当前时间的维修停机记录
	 * @return String 设备的健康状态
	 **/
	private String haveMtnRStopRecord(Map<String, Object> map,
			List<Map<String,Object>>[] stopRecord, String strKey) {
		String value = MapGetter.getString(map, strKey);
		String reHealth = new String();
        if(stopRecord.length != 2){
			return "";
		}
        List<Map<String,Object>> maintList = stopRecord[0];
        List<Map<String,Object>> repairList = stopRecord[1];     
		//设备号
		if(StringUtil.isValid(value)){
			if(maintList.size()>0){
				//维修停机记录
				for(Map<String,Object> maintMap:maintList){
					if(value.equals(MapGetter.getString(maintMap,strKey))){
						reHealth ="2";//健康状态为“维修中”
						break;
					}
				}
			}
			if(!StringUtil.isValid(reHealth)){
				if(repairList.size()>0){
					for(Map<String,Object> repairMap:repairList){
						if(value.equals(MapGetter.getString(repairMap,strKey))){
							reHealth ="3";//健康状态为“保养中”
							break;
						}
					}
				}
			}
		}
		//设备号为""
		else{
			System.out.println("通过设备ID查找此设备是否有维修停机记录时出错——设备ID为空");
		}
		return reHealth;
	}
	/**
	 * 获取当前时间有未解除故障的设备
	 * @return String  ,设备ID1,设备ID2,...,
	 **/
	private String getActiveFltVcl() {
		StringBuffer strFlt = new StringBuffer();
		strFlt.append(" select distinct mp.MsgFH_Vcl_ID as vclid from "+GlobalDBVar.getDBFullName_Conn("Msg_Flt_Happening", "3", null)+" mp");
		strFlt.append(" inner join V_VehicleInfo vv on mp.MsgFH_Vcl_ID = vv.VehicleID");
		strFlt.append(" INNER JOIN "+GlobalDBVar.getDBFullName_Conn("sys_fltism", "1", null)+" ON msgfh_faultspn = sysism_spn  AND msgfh_faultfmi = sysism_fmi");
		strFlt.append(" where vv.UsefulLife >= GETDATE() and vv.Tmnl_SoftEdition is not null");
		strFlt.append(" and vv.Tmnl_SoftEdition<>'' ");//MsgP_Type =1 故障 Msp_State = 3解除
	
		StringBuffer fltvcl = new StringBuffer(",");
		List<Map<String,Object>> list = baseDAO.execQuery(strFlt.toString(), new Object[]{});
		if(list != null){
			for(int i=0;i<list.size();i++){
				if(StringUtil.isValid(MapGetter.getString(list.get(i),"vclid"))){
					fltvcl.append(MapGetter.getString(list.get(i),"vclid"));
					fltvcl.append(",");
				}
			}
		}
		return fltvcl.toString();
	}
	/**
	 * 获取预计完成时间大于当前时间 的维修保养停机记录。
	 * 预计完成时间为null的认为小于当前时间
	 * @return List<Map<String,Object>> 
	 **/
	private List<Map<String,Object>>[] getUndoneStopRecord() {
		StringBuffer strStop = new StringBuffer();
		strStop.append(" select vclid,stoptype,closetime from (");
		//维修
		strStop.append(" select vv.VehicleID as vclid ,'1' as stoptype ,mri1.CloseTime as closetime ");
		strStop.append(" from (select Max(MtnR_CloseTime) as CloseTime,MtnR_Vcl_ID from MtnRepair_Info where MtnR_SysMRT_ID ='1'");
		strStop.append(" and MtnR_PlanComp >= GETDATE() and MtnR_Exp>=GETDATE() group by MtnR_Vcl_ID) as mri1");
		strStop.append(" inner join V_VehicleInfo vv on mri1.MtnR_Vcl_ID = vv.VehicleID");
		strStop.append(" where vv.UsefulLife >= GETDATE() and vv.Tmnl_SoftEdition is not null and vv.Tmnl_SoftEdition<>''");
		strStop.append(" union all ");
		//保养
		strStop.append(" select vv.VehicleID,'2',mri2.CloseTime from ");
		strStop.append(" (select Max(MtnR_CloseTime) as CloseTime,MtnR_Vcl_ID from MtnRepair_Info where MtnR_SysMRT_ID ='2'");
		strStop.append(" and MtnR_PlanComp >= GETDATE() and MtnR_Exp>=GETDATE() group by MtnR_Vcl_ID) as mri2 ");
		strStop.append(" inner join V_VehicleInfo vv on mri2.MtnR_Vcl_ID = vv.VehicleID");
		strStop.append(" where vv.UsefulLife >= GETDATE() and vv.Tmnl_SoftEdition is not null and vv.Tmnl_SoftEdition<>''");
		strStop.append(" ) as tabRM order by closetime desc");
		List<Map<String, Object>> list = baseDAO.execQuery(strStop.toString(), new Object[]{});
		List<Map<String,Object>> repairList = new ArrayList<Map<String,Object>>();
		List<Map<String,Object>> maintList = new ArrayList<Map<String,Object>>();
		if(list!= null){
			for(Map<String,Object> map:list){
				if(MapGetter.getString(map, "stoptype").equals("2")){//保养
					maintList.add(map);
				}
				else if(MapGetter.getString(map, "stoptype").equals("1")){//维修
					repairList.add(map);
				}
				//出错
				else{
					
				}
			}
		}
		List<Map<String,Object>>[] stopList =(List<Map<String,Object>>[])new ArrayList[2];
		stopList[0] = repairList;
		stopList[1] = maintList;
		return stopList;
	}
	/**
	 * 获取当前时间设备开关机状态
	 * @return List<Map<String,Object>>
	 */
	private List<Map<String, Object>> getVclOpenState() {
		StringBuffer strKE = new StringBuffer();
		strKE.append(" select vv.VehicleID as vclid,MsgESL_KeyState AS keystate,MsgESL_EgnState AS enginestate from V_VehicleInfo vv  left join (");
		strKE.append(" select MsgESL_Vcl_ID,MsgESL_KeyState,MsgESL_EgnState from "+GlobalDBVar.getDBFullName_Conn("Msg_EquipmentState_Last", "3", null));
		strKE.append(" ) as abke on abke.MsgESL_Vcl_ID = vv.VehicleID where vv.UsefulLife>=GETDATE() and vv.Tmnl_SoftEdition is not null and vv.Tmnl_SoftEdition<>'' ;");
		return baseDAO.execQuery(strKE.toString(), new Object[]{}) ;
	}
}
